<template>
	<div class="layout-padding">
		<splitpanes>
			<pane size="20">
				<div class="layout-padding-auto layout-padding-view">
					<el-input prefix-icon="search" v-model="filterText" placeholder="请输入关键字搜索" class="mb-2" />
					<el-scrollbar>
						<el-tree
							ref="treeRef"
							:data="treeData.list"
							:props="treeData.defaultProps"
							@node-click="handleNodeClick"
							node-key="id"
							:default-expand-all="true"
							:highlight-current="true"
							:expand-on-click-node="false"
							:filter-node-method="filterNode"
						/>
					</el-scrollbar>
				</div>
			</pane>
			<pane class="ml8">
				<div class="relative layout-padding-auto layout-padding-view">
					<!-- 地图节点 -->
					<div class="w-full h-full" ref="amapRef" id="map"></div>
					<!-- 图层 -->
					<div class="controls">
						<el-button :type="layerControl ? 'primary' : 'info'" size="small" @click="handelLayerControl" icon="setting"></el-button>
						<el-collapse-transition>
							<div v-show="layerControl" class="py-2">
								<div class="flex flex-col w-[26px]">
									<el-tooltip placement="right" content="放大">
										<el-button icon="Plus" type="info" size="small" @click="handleZoom(true)" />
									</el-tooltip>
									<el-tooltip placement="right" content="缩小">
										<el-button class="mt-1 !ml-0" icon="Minus" type="info" size="small" @click="handleZoom(false)" />
									</el-tooltip>
									<el-tooltip placement="right" content="风场" :width="60" effect="light">
										<template #content>
											<div class="w-[60px]">
												<el-radio-group v-model="mapType" @change="handleMapType">
													<el-radio :label="10" size="small">矢量</el-radio>
													<el-radio :label="20" size="small">卫星</el-radio>
												</el-radio-group>
											</div>
										</template>
										<el-button class="mt-3 !ml-0" icon="CopyDocument" type="info" size="small" />
									</el-tooltip>
									<el-tooltip placement="right" content="风场">
										<el-button class="mt-1 !ml-0" icon="WindPower" type="info" size="small" @click="handleWind(windState ? false : true)" />
									</el-tooltip>
									<el-tooltip placement="right" content="名称显隐">
										<el-button class="mt-1 !ml-0" icon="PriceTag" type="info" size="small" @click="toggleName" />
									</el-tooltip>
									<el-tooltip placement="right" content="设备搜索">
										<el-button class="mt-1 !ml-0" size="small" type="success" @click="handleEquipCodeSearch" icon="search"></el-button>
									</el-tooltip>
								</div>
							</div>
						</el-collapse-transition>
					</div>
					<!-- 图例 -->
					<div class="legend">
						<div class="flex items-center text-xs">
							<img :src="MapDevIcon_1" alt="" />
							<div class="ml-1">在线 {{ countState.onLine }}</div>
						</div>
						<div class="flex items-center my-2 text-xs">
							<img :src="MapDevIcon_0" alt="" />
							<div class="ml-1">掉线 {{ countState.offLine }}</div>
						</div>
						<div class="flex items-center text-xs">
							<img :src="MapDevIcon_2" alt="" />
							<div class="ml-1">报警 {{ countState.alarm }}</div>
						</div>
					</div>
					<!-- 搜索设备 -->
					<div class="absolute top-[15px] right-[64px] z-[1009]">
						<div v-show="showSearchEquipCode">
							<el-input
								v-model="equipmentCodeLike"
								placeholder="请输入设备编码"
								ref="iptEquipRef"
								maxlength="30"
								@keyup.enter.native.stop="getDataList()"
								clearable
								size="small"
							>
								<template #append>
									<el-button icon="search" size="small" @click="getDataList()" />
								</template>
							</el-input>
						</div>
					</div>
				</div>
			</pane>
		</splitpanes>
		<el-drawer v-model="drawer" title="详细信息" :destroy-on-close="true" :size="500" @closed="handleClosed">
			<MapDrawer :data="siteData" :siteInfo="siteInfo" :recordTime="recordTime" :airSiteName="airSiteName" :aqiInfo="aqiInfo" />
		</el-drawer>
	</div>
</template>

<script setup lang="ts" name="gisMap">
import { fetchListByTag as fetchList } from '/@/api/platform/airMonitorEquipment';
import { fetchByEquipmentId } from '/@/api/platform/airRealTimeData';
import { fetchAreaList as fetchTreeList } from '/@/api/platform/codeArea';
import { handleTree } from '/@/utils/other';
import { useMessage } from '/@/hooks/message';
import * as L from 'leaflet';
import 'leaflet-velocity/dist/leaflet-velocity';
import 'leaflet.markercluster/dist/MarkerCluster.css';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css';
import 'leaflet.markercluster';
import windJSON from '/@/assets/wind.json';
import waveGif from '/@/assets/images/wave.gif';
import MapDrawer from './components/mapDrawer.vue';
import MapDevIcon_0 from '/@/assets/markers/map-DEV-0.png'; //掉线图标
import MapDevIcon_1 from '/@/assets/markers/map-DEV-1.png'; //在线图标
import MapDevIcon_2 from '/@/assets/markers/map-DEV-2.png'; //警报图标
interface Tree {
	[key: string]: any;
}
const siteId = ref('');
const drawer = ref(false);
const iptEquipRef = ref();
const countState = reactive({
	offLine: 0,
	onLine: 0,
	alarm: 0,
});
const recordTime = ref();
const siteData = ref();
const airSiteName = ref();
const showSearchEquipCode = ref(false);
let m_map: any;
let m_satelliteLayer: any;
let m_vectorLayer: any = null;
let m_velocityLayer: any = null;
let timer: any;
let createMakerCluster: any = null;
let m_markerLayer: any = [];
let m_gifMarker: any;
const filterText = ref('');
const amapRef = ref();
const areaInfo = ref({});
const siteInfo = ref();
const aqiInfo = ref();
const layerControl = ref(false);
const windState = ref(false);
const mapType = ref(10);
const showTags = ref(true);
const treeRef = ref();
const pageData: any = ref([]);
const equipmentCodeLike = ref();
// 区域树使用的数据
const treeData = reactive({
	list: [],
	defaultProps: {
		label: 'name',
	},
});
// 搜索树监听
watch(filterText, (val) => {
	treeRef.value!.filter(val);
});
// 初始化地图
async function initMap() {
	m_satelliteLayer = L.tileLayer('https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', { subdomains: '1234' });
	m_vectorLayer = L.tileLayer('http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {
		subdomains: '1234',
	});
	m_map = L.map('map', {
		resizeEnable: true,
		zoom: 4,
		minZoom: 3,
		maxZoom: 18,
		center: [35.439575, 104.937478],
		preferCanvas: true,
		zoomControl: false,
	});
	m_vectorLayer.addTo(m_map);
	m_map.on('click', function () {
		if (m_gifMarker != undefined) {
			m_gifMarker.removeFrom(m_map);
		}
	});
	createMakerCluster = L.markerClusterGroup({ gridSize: 80, showCoverageOnHover: false });
	m_map.addLayer(createMakerCluster);
	initVelocityLayer();
}
// 风场
const initVelocityLayer = () => {
	m_velocityLayer = L.velocityLayer({
		displayValues: true,
		displayOptions: {
			velocityType: 'Global Wind',
			displayPosition: 'bottomleft',
			displayEmptyString: 'No wind data',
		},
		data: windJSON,
		minVelocity: 0, // used to align color scale
		maxVelocity: 15, // used to align color scale
		velocityScale: 0.01, // modifier for particle animations, arbitrarily defaults to 0.005
		colorScale: ['#808080'], //风场颜色
		onAdd: null,
		onRemove: null,
	});
};
// 点击树
const handleNodeClick = (e: any) => {
	siteId.value = e.id;
	areaInfo.value = e;
	getDataList();
};

const getTreeDate = async () => {
	await fetchTreeList().then((res: any) => {
		const records = res.data;
		if (records.length) {
			treeData.list = handleTree(records, 'id', 'pid', 'children', '1111111111111111111');
			siteId.value = treeData.list[0]?.id;
			getDataList();
			nextTick(() => {
				unref(treeRef)?.setCurrentKey(siteId.value, true);
				handleSwitch(true);
			});
		}
	});
};
const getDataList = () => {
	fetchList({ tag: unref(siteId), equipmentCodeLike: equipmentCodeLike.value }).then((res) => {
		pageData.value = res.data;
		countState.onLine = 0;
		countState.offLine = 0;
		countState.alarm = 0;
		res.data.forEach((d) => {
			if (d.status === 2) {
				if (d.alarmStatus === 2) {
					countState.alarm++;
				} else {
					countState.onLine++;
				}
			} else {
				countState.offLine++;
			}
		});
		if (!m_map) {
			initMap();
		}
		SetMarker();
	});
};
// 定时刷新
const handleSwitch = (val: boolean) => {
	if (val) {
		timer = setInterval(() => {
			getDataList();
		}, 60 * 1000 * 5);
	} else {
		clearInterval(timer);
	}
};
onMounted(() => {
	getTreeDate();
});
onUnmounted(() => {
	handleSwitch(false);
});

const handelLayerControl = () => {
	layerControl.value = !layerControl.value;
};
// 缩放
const handleZoom = (zoom: boolean) => {
	if (zoom) {
		m_map.zoomIn();
	} else {
		m_map.zoomOut();
	}
};
// 风场
const handleWind = (s: boolean) => {
	windState.value = !windState.value;
	if (s) {
		m_velocityLayer.addTo(m_map);
	} else {
		m_velocityLayer.removeFrom(m_map);
	}
};
// 地图切换
const handleMapType = (v: number) => {
	if (v == 10) {
		m_satelliteLayer.removeFrom(m_map);
		m_vectorLayer.addTo(m_map);
	} else {
		m_vectorLayer.removeFrom(m_map);
		m_satelliteLayer.addTo(m_map);
	}
};
// 初始化地图站点标记
const SetMarker = () => {
	handleClosed();
	createMakerCluster && createMakerCluster.clearLayers();
	let markers: any = [];
	if (pageData.value.length) {
		for (let i = 0; i < pageData.value.length; i++) {
			const item = pageData.value[i];
			if (item.longitude && item.latitude) {
				const pos = [item.latitude, item.longitude];
				let icon = L.icon({
					iconUrl: item.status === 2 ? (item.alarmStatus === 2 ? MapDevIcon_2 : MapDevIcon_1) : MapDevIcon_0,
					iconSize: [30, 38],
				});
				let marker = L.marker(pos, { icon: icon });
				marker.extra = item;
				marker.setZIndexOffset(1);
				let icon_0 = L.icon({
					iconUrl: waveGif,
					iconSize: [44, 44],
					iconAnchor: [24, 4],
				});
				marker.sub = L.marker(pos, { icon: icon_0 });
				marker.sub.setZIndexOffset(0);
				marker.bindTooltip(item.name, {
					direction: 'top',
					permanent: true,
					offset: [0, -20],
				});
				marker.on('click', async (e: any) => {
					m_gifMarker && m_gifMarker.removeFrom(m_map);
					m_gifMarker = e.target.sub;
					siteInfo.value = e.target.extra;
					m_gifMarker.addTo(m_map);
					await getDeviceDetail(e.target.extra.id);
					drawer.value = true;
				});
				markers.push(marker);
				createMakerCluster.addLayer(marker);
				m_map.addLayer(createMakerCluster);
			}
		}
		m_markerLayer = markers;
		nextTick(() => {
			// 标记点自适应缩放
			if (markers.length) {
				var group = L.featureGroup(markers); //add markers array to featureGroup
				m_map.fitBounds(group.getBounds());
			}
		});
	}
};
const filterNode = (value: string, data: Tree) => {
	if (!value) return true;
	return data.name.includes(value);
};
// 获取设备实时数据
const getDeviceDetail = async (id: string) => {
	try {
		const res = await fetchByEquipmentId({ monitorEquipmentId: id });
		recordTime.value = res.data.recordTime;
		airSiteName.value = res.data.airSiteName;
		siteData.value = res.data.detail;
		aqiInfo.value = res.data.aqi;
	} catch (err: any) {
		useMessage().error(err.msg);
	}
};
// 显示名称
const toggleName = () => {
	for (const i in m_markerLayer) {
		const marker = m_markerLayer[i];
		if (showTags.value) {
			marker.closeTooltip();
		} else {
			marker.openTooltip();
		}
	}
	showTags.value = !showTags.value;
};
const handleClosed = () => {
	m_gifMarker && m_gifMarker.removeFrom(m_map);
};
const handleEquipCodeSearch = () => {
	showSearchEquipCode.value = !showSearchEquipCode.value;
	if (showSearchEquipCode.value) {
		unref(iptEquipRef)?.focus();
	}
};
</script>

<style lang="scss" scoped>
:deep(.amap-marker-label) {
	color: #000;
	background: #00e400;
	border: unset;
	border-radius: 4px;
}
:deep(.amap-logo) {
	display: none !important;
}
:deep(.amap-copyright) {
	display: none !important;
}

:deep(.el-drawer__header) {
	margin-bottom: 0;
}
:deep(.leaflet-control) {
	display: none !important;
}

.controls {
	position: absolute;
	top: 15px;
	right: 15px;
	z-index: 1000;
}
.legend {
	font-size: 12px;
	position: absolute;
	top: 15px;
	left: 15px;
	z-index: 1000;
	padding: 6px 12px;
	border-radius: 6px;
	background-color: rgba($color: #fff, $alpha: 0.5);
	img {
		width: 20px;
		height: 24px;
	}
}
</style>
